class DoorRenderer : public IBlockRenderer
{
public:
	ITexture *Texture;
	Point2i Position;

	DoorRenderer(ITexture *texture, const Point2i &offset) :
		Texture(texture),
		Position(offset)
	{
	}

	int GetTypeData(const int &data) { return 0; }

	void Render(Schematic *schematic, RendererBase *renderer, const Block &block, const Point3i &position)
	{
		bool isBottom = (block.Data & 0x08) == 0;
		Block topBlock = Block::Empty, bottomBlock = Block::Empty;

		if (isBottom)
		{
			bottomBlock = block;
			topBlock = schematic->GetBlock(position.X, position.Y + 1, position.Z);
		}
		else
		{
			topBlock = block;
			bottomBlock = schematic->GetBlock(position.X, position.Y - 1, position.Z);
		}

		bool hingeOnRight = true;
		bool closed = true;
		byte direction = 0;

		if (bottomBlock != Block::Empty && topBlock != Block::Empty && topBlock.ID == bottomBlock.ID)
		{
			hingeOnRight = (topBlock.Data & 0x01) == 0;
			closed = (bottomBlock.Data & 0x04) == 0;
			direction = (byte)((bottomBlock.Data & 0x03));
		}
		
		renderer->Translate(8, 8, 8);
		renderer->Rotate(((direction - 1) % 4) * -90, 0, 1, 0);
		renderer->Translate(-8, -8, -8);
		
		if (!closed)
		{
			Point3f translateOrigin;
			float dir;

			if (hingeOnRight)
			{
				translateOrigin = Point3f(16 - 1.5f, 0, 1.5f);
				dir = 90;
			}
			else
			{
				translateOrigin = Point3f(1.5f, 0, 1.5f);
				dir = -90;
			}

			renderer->Translate(translateOrigin.X, translateOrigin.Y, translateOrigin.Z);
			renderer->Rotate(dir, 0, 1, 0);
			renderer->Translate(-translateOrigin.X, -translateOrigin.Y, -translateOrigin.Z);
		}

		Point2i tex((Position.X * 16), ((Position.Y + ((block.Data & 0x8) == 0 ? 1 : 0)) * 16));

		Face front(Point3f(16, 0, 0), Point3f(0, 0, 0), Point3f(0, 16, 0), Point3f(16, 16, 0), Colorb::White, Texture, tex, 16, 16);

		if (!hingeOnRight)
			front.FlipX();

		renderer->Draw(front);

		Face back(Point3f(0, 0, 3), Point3f(16, 0, 3), Point3f(16, 16, 3), Point3f(0, 16, 3), Colorb::White, Texture, tex, 16, 16);

		if (hingeOnRight)
			back.FlipX();

		renderer->Draw(back);

		renderer->Draw(Face(Point3f(0, 0, 0), Point3f(0, 0, 3), Point3f(0, 16, 3), Point3f(0, 16, 0), Colorb::White, Texture, tex, 3, 16).FlipX());
		renderer->Draw(Face(Point3f(16, 0, 3), Point3f(16, 0, 0), Point3f(16, 16, 0), Point3f(16, 16, 3), Colorb::White, Texture, tex, 3, 16));
		renderer->Draw(Face(Point3f(0, 0, 0), Point3f(16, 0, 0), Point3f(16, 0, 3), Point3f(0, 0, 3), Colorb::White, Texture, tex, 16, 3));
		renderer->Draw(Face(Point3f(0, 16, 3), Point3f(16, 16, 3), Point3f(16, 16, 0), Point3f(0, 16, 0), Colorb::White, Texture, tex, 16, 3));
	}
};